/*
 * @Author: caiwanli 651943559@qq.com
 * @Date: 2024-01-03 10:05:45
 * @LastEditors: caiwanli 651943559@qq.com
 * @LastEditTime: 2024-01-22 15:23:15
 * @FilePath: /task_sche-binder/src/planner/plan_node.cpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置
 * 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "catalog.hpp"
#include "logical_type.hpp"
#include "nest_loop_join_plan.h"
#include "planner.hpp"
#include "projection_plan.h"
#include "seq_scan_plan.h"
#include <arrow/type_fwd.h>
#include <cstdio>

namespace DaseX {

auto SeqScanPlanNode::InferScanSchema(const BoundBaseTableRef &table)
    -> arrow::Schema {
  arrow::FieldVector filed_vector;
  std::vector<std::shared_ptr<Field>> fileds;
  auto temp_schema = table.schema_;

  for (auto f : temp_schema.field_names()) {
    std::shared_ptr<arrow::Field> field_ = temp_schema.GetFieldByName(f);
    std::string name = field_->name();

    printf("in SeqScanPlanNode InferScanSchema , check table %s field %s\n",
           table.table_.c_str(), name.c_str());

    // 目前这里类型先统一int了
    auto col_name = table.table_ + "." + name;
    fileds.push_back(
        std::move(std::make_shared<Field>(col_name, LogicalType::INTEGER)));
  }

  for (auto i = 0; i < fileds.size(); i++) {
    filed_vector.push_back(fileds[i]->field);
  }
  auto schema = arrow::Schema(filed_vector);
  return arrow::Schema(schema);
}

auto NestedLoopJoinPlanNode::InferJoinSchema(const AbstractPlanNode &left,
                                             const AbstractPlanNode &right)
    -> arrow::Schema {
  arrow::FieldVector filed_vector;
  std::vector<std::shared_ptr<Field>> fileds;

  printf("========================================================\n");
  auto temp_schema = left.output_schema_;

  for (auto f : temp_schema->field_names()) {
    std::shared_ptr<arrow::Field> field_ = temp_schema->GetFieldByName(f);
    fileds.push_back(
        std::move(std::make_shared<Field>(f, LogicalType::INTEGER)));
    printf("in njl left InferScanSchema , check field %s\n", f.c_str());
  }

  temp_schema = right.output_schema_;
  for (auto f : temp_schema->field_names()) {
    std::shared_ptr<arrow::Field> field_ = temp_schema->GetFieldByName(f);
    std::string name = field_->name();
    fileds.push_back(
        std::move(std::make_shared<Field>(f, LogicalType::INTEGER)));
    printf("in njl right InferScanSchema , check field %s\n", name.c_str());
  }
  //   for (const auto &column : left.OutputSchema().GetColumns()) {
  //     schema.emplace_back(column);
  //   }
  //   for (const auto &column : right.OutputSchema().GetColumns()) {
  //     schema.emplace_back(column);
  //   }
  for (auto i = 0; i < fileds.size(); i++) {
    filed_vector.push_back(fileds[i]->field);
  }
  auto schema = arrow::Schema(filed_vector);

  for (auto f : schema.field_names()) {
    printf("final join outputschema : %s\n", f.c_str());
  }
  return arrow::Schema(schema);
}

auto ProjectionPlanNode::InferProjectionSchema(
    const std::vector<AbstractExpressionRef> &expressions) -> arrow::Schema {
  arrow::FieldVector filed_vector;
  std::vector<std::shared_ptr<Field>> fileds;

  for (const auto &expr : expressions) {
    auto type_id = expr->GetReturnType();
    fileds.push_back(
        std::move(std::make_shared<Field>("unnamed_expr", type_id)));
  }

  for (auto i = 0; i < fileds.size(); i++) {
    filed_vector.push_back(fileds[i]->field);
  }

  auto schema = arrow::Schema(filed_vector);
  return arrow::Schema(schema);
}

auto ProjectionPlanNode::RenameSchema(const arrow::Schema &schema,
                                      const std::vector<std::string> &col_names)
    -> arrow::Schema {

  size_t idx = 0;
  arrow::FieldVector filed_vector;
  //   for (const auto &column : schema.GetColumns()) {
  //     output.emplace_back(Column(col_names[idx++], column));
  //   }
  for (auto f : schema.field_names()) {
    printf("RenameSchema 1\n");
    std::shared_ptr<arrow::Field> field_ = schema.GetFieldByName(f);
    printf("RenameSchema 2\n");

    printf("fields name : %s\n", f.c_str());
  }
  printf("RenameSchema finish\n");
  return schema;
}


} // namespace DaseX